package com.artup.service.impl;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.artup.common.Constants;
import com.artup.common.OrderStatus;
import com.artup.common.ResponseResult;
import com.artup.dao.MaterialEditDao;
import com.artup.dao.OrderDao;
import com.artup.dao.WorksDao;
import com.artup.pojo.MaterialEdit;
import com.artup.pojo.Works;
import com.artup.service.WorksService;
import com.artup.util.CommonUtils;
import com.artup.util.file.PropertiesUtils;
import com.artup.util.image.ImageUtil;
import com.artup.util.os.OperationSystemInfo;
import com.artup.util.pdf.PdfUtil.PdfParam;
import com.artup.util.shell.ChmodShell;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service( value = "pdfService" )
public class PdfServiceImpl {
	private static final Logger LOGGER = LoggerFactory.getLogger(WorksService.class);
	
	@Autowired
	private OrderDao orderDao;
	
	@Autowired
	private WorksDao worksDao;

	@Autowired
	private MaterialEditDao materialEditDao;

	@Autowired
	private PdfCreator pdfCreate;
	
	@Resource( name = "threadExecutorService" )
	private ThreadExecutorService threadExecutorService;
	
	private List<MaterialEdit> getMaterialEdit(Works works){
		List<MaterialEdit> materialEditList = null;
		
		try {
			materialEditList = this.materialEditDao.selectMaterialEditByWorksId(works.getId());
		} catch (SQLException e) {
			LOGGER.error("根据【作品ID】查询【素材编辑】列表 - 失败！", e);
		}
		
		if(CommonUtils.isEmpty(materialEditList)) {
			return null;
		}
		
		for(int index = 0; index < materialEditList.size(); index++) {
			MaterialEdit materialEdit = materialEditList.get(index);
			
			if(null == materialEdit) {
				continue;
			}
			
			/*String action = materialEdit.getAction();
			
			if(StringUtils.isNotBlank(action)) {
				ImageEditAction imageEditAction = JSONObject.parseObject(action, ImageEditAction.class);
				
				if(null != imageEditAction) {
					materialEdit.setWidth(imageEditAction.getWidth());
					materialEdit.setHeight(imageEditAction.getHeight());
					materialEdit.setX(imageEditAction.getX());
					materialEdit.setY(imageEditAction.getY());
				}
			}*/
			if(StringUtils.isNotBlank(materialEdit.getEditedMaterialPath())) {
				int editedWorksWidth = ImageUtil.getImageWidth(materialEdit.getEditedMaterialPath());
				int editedWorksHeight = ImageUtil.getImageHeight(materialEdit.getEditedMaterialPath());
				
				materialEdit.setWidth(editedWorksWidth);
				materialEdit.setHeight(editedWorksHeight);
			}
		}
		
		return materialEditList;
	}
	
	/**
	 * 创建pdf
	 * @param works
	 * @throws Exception
	 */
	private void buildEditPdf(Works works, String orderCode)throws Exception{
		
		//生成pdf
//		Command<PdfParam, String> pdfCreate = SpringContextUtils.getBean("pdfCommond");
		if(null == pdfCreate){
			log.error("未找到 PDF 服务！");
			
			return;
		}
		
		String memberFolderPath = (PropertiesUtils.getValue("works.pdf.path").endsWith("/") ? PropertiesUtils.getValue("works.pdf.path") : PropertiesUtils.getValue("works.pdf.path") + File.separator) + works.getPassportId();
		File memberFilePath = new File(memberFolderPath);
		if(!memberFilePath.exists()) {
			memberFilePath.mkdirs();
			
			if(OperationSystemInfo.isLinux()) {
				ChmodShell.updateFolderAuth(memberFilePath.getAbsolutePath());
			}
		}
		
		String pdfFileDirectoryPath = memberFolderPath + File.separator + orderCode;
//		String pdfFileDirectoryPath = PropertiesUtils.getValue("works.pdf.path") + File.separator + works.getPassportId() + File.separator + orderCode;
//		String pdfFileDirectoryPath = FolderUtils.getStoragePath(PropertiesUtils.getValue("works.pdf.path"), works.getPassportId()) + File.separator + orderCode;

		PdfParam pdfParam = new PdfParam();
		
		File pdfDirectoryFile = new File(pdfFileDirectoryPath);
		if(!pdfDirectoryFile.exists()) {
			pdfDirectoryFile.mkdirs();

			if(OperationSystemInfo.isLinux()) {
				ChmodShell.updateFolderAuth(pdfDirectoryFile.getAbsolutePath());
			}
		}
		
		String pdfFilePath = pdfFileDirectoryPath.endsWith(File.separator) ? pdfFileDirectoryPath + works.getId() + ".pdf" : pdfFileDirectoryPath + File.separator + works.getId() + ".pdf";

		List<MaterialEdit> materialEditList = this.getMaterialEdit(works);
	
		pdfParam.setDestPdfFilePath(pdfFilePath);
		
		try {
			this.orderDao.updateOrderStatus(orderCode, OrderStatus.getValue(OrderStatus.PDF_CREATING));
		} catch (SQLException e) {
			LOGGER.error("根据【订单号】更新【订单状态】 - 失败！");
		}
		
		pdfCreate.execute(pdfParam, materialEditList);
		
		this.orderDao.updateOrderStatus(orderCode, OrderStatus.getValue(OrderStatus.PDF_CREATED));
		
		this.worksDao.updateWorksPdfPathById(works.getId(), pdfFilePath);
		
		if(OperationSystemInfo.isLinux()) {
			ChmodShell.updateFolderAuth(pdfFilePath);
		}

		log.info("PDF 制作成功，pdfPath = {}", pdfFilePath);
	}
	
	@Async
	public ResponseResult createPdf(final String orderCode){
		log.info("开始制作 PDF，orderCode = {}", orderCode);
		
		ResponseResult responseResult = new ResponseResult();
		
		if(StringUtils.isBlank(orderCode)){
			responseResult.setStatus(Constants.ACTION_STATUS_PARAMETER_EMPTY);
			responseResult.setMessage("【订单号】不可为空！");
			
			return responseResult;
		}
		
		List<Works> worksList = null;	// 作品列表
		try {
			worksList = this.worksDao.selectWorksListByOrderCode(orderCode);
		} catch (SQLException e) {
			LOGGER.error("根据【订单号】查询【作品列表】 - 失败！", e);
			
			responseResult.setStatus(Constants.ACTION_STATUS_FAILURE);
			responseResult.setMessage("根据【订单号】查询【作品列表】 - 失败！");
			
			return responseResult;
		}
		
		if(worksList == null || worksList.isEmpty()){
			responseResult.setStatus(Constants.ACTION_STATUS_PARAMETER_EMPTY);
			responseResult.setMessage("此订单无作品！");
			
			return responseResult;
		}
		
		for(final Works works : worksList){
			threadExecutorService.getExecutorService().execute(new Runnable(){
				@Override
				public void run() {
					try{
						buildEditPdf(works, orderCode);
					}catch(Exception e){
						log.error(e.getMessage(), e);
					}
				}
			});
		}
		
		responseResult.setStatus(Constants.ACTION_STATUS_SUCCESS);
		responseResult.setMessage("创建 PDF 成功。");
		
		return responseResult;
	}

	/**
	 * 查询【PDF 路径】列表
	 * @param passportId 通行证ID
	 * @param orderCode 订单号
	 * @return 【PDF 路径】列表
	 */
	public ResponseResult queryPdfPathList(Integer passportId, String orderCode){
		log.info("passportId = {}，orderCode = {}", passportId, orderCode);
		
		ResponseResult responseResult = new ResponseResult();
		
		if(StringUtils.isBlank(orderCode)){
			responseResult.setStatus(Constants.ACTION_STATUS_PARAMETER_EMPTY);
			responseResult.setMessage("【订单号】不可为空！");
			
			return responseResult;
		}
		
		String pdfPath = PropertiesUtils.getValue("works.pdf.path") + File.separator + passportId + File.separator + orderCode + File.separator;
		
		File pdfFolder = new File(pdfPath);
		
		if(!pdfFolder.exists()) {
			responseResult.setStatus(Constants.ACTION_STATUS_PARAMETER_EMPTY);
			responseResult.setMessage("无此文件夹！");
			
			return responseResult;
		}
		
		if(pdfFolder.isDirectory()){
			String [] pdfFiles = pdfFolder.list();

			if(null != pdfFiles && 0 < pdfFiles.length) {
				List<String> pdfList = new ArrayList<String>();
				
				for(int index = 0; index < pdfFiles.length; index++){
					File pdfFile = new File(pdfPath + File.separator + pdfFiles[index]);
					
					if(pdfFile.isFile()) {
						String pdfAbsolutePath = pdfFile.getAbsolutePath();
						LOGGER.info("pdfFile = {}", pdfAbsolutePath);
						int pdfIndex = pdfAbsolutePath.indexOf("pdf");
						
						pdfList.add(PropertiesUtils.getValue("artup.mobile.url.perfix") + pdfAbsolutePath.substring(pdfIndex, pdfAbsolutePath.length()));
					}
				}
				
				responseResult.setData(pdfList);
				System.out.println(pdfList);
			}
		}
		
		responseResult.setStatus(Constants.ACTION_STATUS_SUCCESS);
		responseResult.setMessage("查询【PDF 路径】列表 - 成功。");
		
		return responseResult;
	}
}
